package com.jse.io.nio.network.new1.mine.test;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class Client extends Thread {
	private Selector selector;
	
	@Override
	public void run() {
		try {
			selector = Selector.open();
			
//			SocketChannel client = SocketChannel.open(new InetSocketAddress("127.0.0.1", 999));
			SocketChannel client = SocketChannel.open();
			client.configureBlocking(false);
			
			boolean isconn = client.connect(new InetSocketAddress("127.0.0.1", 999));
			client.register(selector, SelectionKey.OP_CONNECT);
			
			while(true) {
				selector.select();
				
				Set<SelectionKey> set = selector.selectedKeys();
//				System.out.println(set.size());
				Iterator<SelectionKey> iterator = set.iterator();
				while(iterator.hasNext()) {
					SelectionKey connKey = iterator.next();
					
					iterator.remove();
//					System.out.println(set.size());
					if (!connKey.isValid()) {
						continue;
					}
					
					if (connKey.isConnectable()) {
						this.connect(connKey);
					}
					//连接就绪后读取数据
					if (connKey.isReadable()) {
						this.read(connKey);
					}
					//连接就绪后向服务器写数据
					if (connKey.isWritable()) {
						this.write(connKey);
					}
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * OP_CONNECT、OP_WRITE都是写操作不能同时存在
	 * @param connKey
	 */
	public void connect(SelectionKey connKey) {
		try {
			SocketChannel clientfd = (SocketChannel) connKey.channel();
			
			if (clientfd.isConnectionPending()) {
				clientfd.finishConnect();
			}
			
//			clientfd.write(ByteBuffer.wrap("hello server".getBytes()));
			
			clientfd.configureBlocking(false);
			clientfd.register(this.selector, SelectionKey.OP_WRITE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void read(SelectionKey connKey) {
		try {
			SocketChannel clientfd = (SocketChannel) connKey.channel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			clientfd.read(buffer);
			System.out.println("Client : " + new String(buffer.array()));
			
//			clientfd.configureBlocking(false);
//			clientfd.register(this.selector, SelectionKey.OP_WRITE);
			
//			int readyOps = connKey.readyOps();
//			System.out.println(connKey.interestOps() & ~readyOps);
//			connKey.interestOps(connKey.interestOps() & ~readyOps);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	public void write(SelectionKey connKey) {
		try {
			SocketChannel clientfd = (SocketChannel) connKey.channel();
//			ByteBuffer buffer = ByteBuffer.allocate(1024);
			clientfd.write(ByteBuffer.wrap("hello server".getBytes()));
			
			clientfd.configureBlocking(false);
			clientfd.register(this.selector, SelectionKey.OP_READ);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new Client().start();
	}
}
